import os
import cgi
import urllib
import sys
import datetime

from datetime import date
from django.utils import simplejson as json
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import memcache
import facebook
from models import *
import shared

_FbApiKey = '102d3b67b1e319439396fed4c2e0eb58'
_FbSecret = 'cecf1af6fefde54784a9ff34b2403a37'
_LastfmApiKey = 'ed892c0f6430d25a96238ed1c87e2920'
_LastfmSecret = '91df7d1a616f1ab38b8635e660c02bd7'

# TODOs:
# 1) Search all acts - not only primary
# 2) Filter Escape Characters in Name
class TicketList(webapp.RequestHandler):
    def get(self):

        #Decode URL
        artist = cgi.escape(self.request.get('artist'))
        venue = cgi.escape(self.request.get('venue'))
        date = cgi.escape(self.request.get('date'))
        sortoption = cgi.escape(self.request.get('sortoption'))
        
        #Get the Event ID
        eventData = getEventData(artist, date)
        if len(eventData['response']['docs']) == 0:
            data = []
            self.response.out.write(json.dumps(data))
            return
        eventJSON = eventData['response']['docs'][0]
        eventID = int(eventJSON['event_id'])
        
        #Get important URLs
        imageURL = "http://www.stubhub.com/data/venue_maps/"+eventJSON['geography_parent']+"/"+eventJSON['image_url']
        artistURL = "http://www.stubhub.com/"+eventJSON['genreUrlPath']
        venueURL = "http://www.stubhub.com/"+eventJSON['geoUrlPath']
        eventURL = artistURL+"/"+eventJSON['urlpath']
        
        description = eventJSON['description'] 
        
        #Get the list of tickets
        ticketData = getTicketData(eventID, sortoption)
        
        #Create new json list with ticket and event data
        data = {}
        data['tickets'] = ticketData['response']['docs']
        data['artist'] = artist
        data['venue'] = venue
        data['date'] = date
        data['description'] = description
        data['imageURL'] = imageURL
        data['artistURL'] = artistURL
        data['venueURL'] = venueURL
        data['eventURL'] = eventURL
        
        #Update cache
        if memcache.get(str(eventID)) is None:
            memcache.add(str(eventID), eventURL, 3600)
        else:
            memcache.replace(str(eventID), eventURL, 3600)
        
        #Output the data
        self.response.out.write(json.dumps(data))

    def post(self):
        TicketList.get(self)


class FilterTickets(webapp.RequestHandler):
    
    def post(self):
        eventID = cgi.escape(self.request.get('eventID'))
        qty = cgi.escape(self.request.get('quantity'))
        sortoption = cgi.escape(self.request.get('sortoption'))
        minPr = cgi.escape(self.request.get('minPr'))
        maxPr = cgi.escape(self.request.get('maxPr'))
        
        ticketData = getTicketData(eventID, sortoption=sortoption, quantity=qty, minPrice=minPr, maxPrice=maxPr)
        
        eventURL = memcache.get(eventID)
        
        if eventURL is None:
            eventData = getEventData(eventID=eventID)
            eventJSON = eventData['response']['docs'][0]
            artistURL = "http://www.stubhub.com/"+eventJSON['genreUrlPath']
            eventURL = artistURL+"/"+eventJSON['urlpath']
            
            memcache.add(eventID, eventURL, 3600)

        data = {}
        data['tickets'] = ticketData['response']['docs']
        data['eventURL'] = eventURL
        
        self.response.out.write(json.dumps(data))
                

class BeginTrack(webapp.RequestHandler):
    
    def post(self):
        
        #Decode URL
        eventID = cgi.escape(self.request.get('eventID'))
        
        #instantiate facebook
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        if fb.check_session(self.request) and fb.added:
            pass
        else:
            url = fb.get_add_url('http://apps.facebook.com/concert-deals/concert_search')
            self.response.out.write(json.dumps([False,url]))
            return
        
        # Get the information about the user.
        fbUser = fb.users.getInfo( [fb.uid], ['uid', 'name'])[0]       
        user = getUser(fbUser['uid'])
        if (not existsInList(user.event_ids,eventID)):
            user.event_ids += [eventID]
            user.put()
        
        #If tracker already exists
        trackerList = db.GqlQuery("SELECT * FROM Trackers WHERE event_id = :1", eventID)
        if trackerList.count() > 0:
            return

        ticketData = getTicketData(eventID)
        ticketList = ticketData['response']['docs']
        
        sectionIDList = []
        
        for ticket in ticketList:
            
            exists = False            
            for sectionID in sectionIDList:
                if sectionID == ticket['venue_config_sections_id']:
                    exists = True
                    break
            
            if not exists:
                sectionName = ticket['alias']
                sectionID = ticket['venue_config_sections_id']
                priceList = [str(getMinPrice(eventID, sectionID))]
                dateList = [getCurrentDateTime()]
                
                tracker = Trackers(event_id=eventID,section_name=sectionName,section_id=sectionID,min_prices=priceList,dates=dateList)
                tracker.put()
                
                sectionIDList.append(ticket['venue_config_sections_id'])


# TODO: Check to see if new sections are available
class UpdateTracks(webapp.RequestHandler):
    def get(self):
        trackers = db.GqlQuery("SELECT * FROM Trackers")
        
        for tracker in trackers:
            
            eventID = tracker.event_id
            sectionID = tracker.section_id
            priceList = tracker.min_prices
            dateList = tracker.dates
            
            priceList.append(str(getMinPrice(eventID, sectionID)))
            dateList.append(getCurrentDateTime())

            tracker.put()
    
    def post(self):
        UpdateTracks.get(self);


class ViewTracks(webapp.RequestHandler):
    def get(self):
        template_values = {}        
        path = os.path.join(os.path.dirname(__file__), 'html/tracks.html')
        self.response.out.write(template.render(path, template_values))
    
    def post(self):
        fb = facebook.Facebook(_FbApiKey, _FbSecret)
        if fb.check_session(self.request) and fb.added:
                pass
        else:
                # If not redirect them to your application add page.
                url = fb.get_add_url('http://apps.facebook.com/concert-deals/concert_search')
                self.response.out.write('<script language="javascript">top.location.href="' + url + '"</script>')
                return
        # Get the information about the user.
        a = fb.uid;
        fbUser = fb.users.getInfo( [fb.uid], ['uid', 'name'])[0]       
        user = getUser(fbUser['uid'])
        trackerList = []
        for eventID in user.event_ids:
        
            queryObj = db.GqlQuery("SELECT * FROM Trackers WHERE event_id = :1 ORDER BY event_id, section_id",eventID) 
            sectionList = []
            tmpID = -1;
            for tracker in queryObj:
                
                #new event
                if tmpID <> tracker.event_id:
                    if tmpID <> -1:
                        trackerList.append(sectionList)
                        sectionList = []
                    tmpID = tracker.event_id
                
                #Get the Event Data
                eventData = getEventData(eventID=tracker.event_id)
                eventJSON = eventData['response']['docs'][0]
                artist = eventJSON['act_primary']
                venue = eventJSON['name_primary']
                date = eventJSON['event_date_local']
            
                    #Get important URLs
                imageURL = "http://www.stubhub.com/data/venue_maps/"+eventJSON['geography_parent']+"/"+eventJSON['image_url']
                
                sectionList.append({
                "priceList": tracker.min_prices,
                "dateList": tracker.dates,
                "sectionName": tracker.section_name,
                "eventID": tracker.event_id,
                
                "artist": artist,
                "venue": venue,
                "date": date,
                
                "imageURL": imageURL,
                });
            
            trackerList.append(sectionList)
        
        self.response.out.write(json.dumps(trackerList)) 

class RemoveTracks:
    def get(self):
        a = 0 
        

#Method which returns the user object for the fb id
#creates a new user object in case it doesnt exist
def getUser(fb_id):
        users = Users.gql("WHERE fb_id = :fbid", fbid = fb_id)

        if (users.count(1) == 0):
            newUser = Users()
            newUser.fb_id = fb_id
            newUser.put()
            return newUser
        return users.get()
    
def existsInList(list,element):
    for elems in list:
        if element == elems:
            return True
    return False

def getMinPrice(eventID, sectionID):
    ticketData = getTicketData(eventID, "none", sectionID)
    ticketJSONList = ticketData['response']['docs']

    min_price = sys.maxint;
    
    for ticketJSON in ticketJSONList:
        if min_price > ticketJSON['curr_price']:
            min_price = ticketJSON['curr_price'];

    return min_price;

def getCurrentDateTime():
    return datetime.datetime.today().strftime("%a, %d %b %Y %H:%M:%S")

def getEventData(artist="", date="", venue="", eventID=""):
    url = "http://www.stubhub.com/listingCatalog/select/?q="            #Listing Service
    url += "%2B+stubhubDocumentType%3Aevent%0D%0A"                      #Type: Event
    
    if artist <> "":
        url += "%2B+act_primary%3A" + urllib.quote(artist) + "%0D%0A"       #Artist
    
    if venue <> "":
        url += "%2B+name_primary%3A" + urllib.quote(venue) + "%0D%0A"       #Venue
        
    if date <> "":
        url += "%2B+event_date_local%3A" + urllib.quote(date) + "%0D%0A"    #Date
        
    if eventID <> "":
        url += "%2B+event_id%3A" + eventID + "%0D%0A"                       #Event ID
        
    url += "&version=2.2&indent=on&wt=json"
    
    return json.load(urllib.urlopen(url));

def getTicketData(eventID, sortoption="none", sectionID="none", quantity="-1", minPrice="-1", maxPrice="-1"):
    
    #Get sort string
    if sortoption == "price":
        sortstring = "curr_price"
    elif sortoption == "section":
        sortstring = "venue_config_sections_id"
    
    url = "http://www.stubhub.com/listingCatalog/select/?q="            #Listing Service
    url += "%2B+stubhubDocumentType%3Aticket%0D%0A"                     #Type: Ticket
    url += "%2B+event_id%3A" + urllib.quote(str(eventID)) + "%0D%0A"    #Event ID
    
    if sectionID <> "none":
        url += "%2B+venue_config_sections_id%3A" + urllib.quote(sectionID) + "%0D%0A"
        
    if quantity <> "-1":
        url += "%2B+quantity%3A%5B"+ quantity +"%20TO%20*%5D%0D%0A"     #Quantity
    
    if minPrice <> "-1":
        url += "%2B+curr_price%3A%5B"+ minPrice +"%20TO%20" + maxPrice + "%5D%0D%0A"
    
    if sortoption <> "none":
        url += ";" + sortstring + "%20asc" + "%0D%0A"                   #Sort
    
    url += "&version=2.2&indent=on&wt=json"
    
    return json.load(urllib.urlopen(url));
